home *** CD-ROM | disk | FTP | other *** search
- /* status.c -- routines for extracting status information from the machine
- *
- * %W%
- *
- * Authors: Chris Jalbert
- * Copyright 1996 Apple Computer, Inc.
- * All Rights Reserved.
- *
- * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF APPLE COMPUTER, INC.
- * The copyright notice above does not evidence any actual or
- * intended publication of such source code.
- *
- * History:
- * 8/27/96 Chris Jalbert
- * Initial check in of new sample.
- * 10/9/96 Chris Jalbert
- * Changed AIX code from using pipes to accessing services directly.
- */
-
- #if defined(_AIX) && !defined(SIMPLIFIED)
- # ifdef _ALL_SOURCE
- # include <sys/select.h> /* required for fd_set and select() */
- # else
- # define _ALL_SOURCE
- # include <sys/select.h> /* required for fd_set and select() */
- # undef _ALL_SOURCE
- # endif /* _ALL_SOURCE */
- #endif /* _AIX && SIMPLIFIED */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <signal.h>
- #include <time.h>
-
- #include "tridentd.h"
- #include "debug.h"
-
-
- #ifdef _AIX
- #include <fcntl.h> /* for unbuffered I/O */
- #include <utmp.h> /* for utmp structs and macros */
- #include <nlist.h> /* for struct nlist stuff used by _GetLoads() */
-
- extern int knlist (struct nlist *, int, int) ;
-
- #else /* _AIX */
- #include <Timer.h>
-
- #define _CountUsers() 1
- #define _GetLoads(dp) dp[0] = dp[1] = dp[2] = 0.5
- #endif /* _AIX */
-
-
- #define MIN_S (time_t)60 /* 1 min = MIN_S seconds... */
- #define HOUR_S (60 * MIN_S)
- #define DAY_S (24 * HOUR_S)
- #define HOUR_M (time_t)60 /* 1 hour = HOUR_M minutes */
- #define DAY_M (24 * HOUR_M)
-
-
- /******************************************************************************
- ==> Private Globals <==
- ******************************************************************************/
- #ifdef _AIX
- static time_t _BootTime ;
- static int _UTmp ;
- #endif /* _AIX */
-
-
- /******************************************************************************
- ==> Static Functions <==
- ******************************************************************************/
- #ifdef _AIX
- /*-----------------------------------------------------------------------------
- _CountUsers() walks the utmp file looking for user processes.
- -----------------------------------------------------------------------------*/
- static int _CountUsers (void)
- {
- register struct utmp *spResult ;
- register int nUsers = 0 ;
-
- /* Look for user entries in the utmp file. */
- while (NULL != (spResult = getutent ()))
- if ((spResult->ut_type == USER_PROCESS)
- && spResult->ut_user[0])
- nUsers++ ;
- /* Close the file so we start from scratch next time. */
- endutent () ;
- return nUsers ;
- }
-
- /*-----------------------------------------------------------------------------
- _GetLoads() makes use of the kernel version of the standard Unix tool,
- nlist, which searches name lists in executables. Although buffered I/O
- does seem to work, the docs say only unbuffered I/O is valid.
- -----------------------------------------------------------------------------*/
- /*
- * Must agree with SBITS in sys/prod/sched.c
- */
- #define FSHIFT 16
- #define FSCALE (1<<FSHIFT)
-
- static void _GetLoads (
- double *dpArray)
- {
- static struct nlist _nl = { "avenrun" } ;
- unsigned long runarray [3] = {0, 0, 0} ;
- register int kmem ;
-
- /* Find the "avenrun" entry in the kernel. */
- if (-1 == (kmem = open ("/dev/kmem", O_RDONLY)))
- return ;
- knlist (&_nl, 1, sizeof (struct nlist)) ;
- if (_nl.n_value == lseek (kmem, _nl.n_value, SEEK_SET))
- read (kmem, runarray, sizeof (runarray)) ;
- close (kmem) ;
-
- /* Convert the avenrun to doubles. */
- *dpArray++ = ((double) runarray[0]) / FSCALE ;
- *dpArray++ = ((double) runarray[1]) / FSCALE ;
- *dpArray++ = ((double) runarray[2]) / FSCALE ;
- }
- #endif /* _AIX */
-
-
- /******************************************************************************
- ==> Global (Exported) Functions <==
- ******************************************************************************/
-
- int GetUptimeString (
- char *szpBuf,
- long lLength)
- {
- register char *szpBuffer = szpBuf ;
- register time_t tUptime = time (NULL) ;
- register long lDays, lHours ;
- register int nUsers ;
- time_t tCurrent = tUptime ;
- register struct tm *tmCurrent = localtime (&tCurrent) ;
- UnsignedWide uptime ;
- double daLoads [3] ;
-
- #ifdef _AIX
- tUptime -= _BootTime ;
- tUptime += 30 ;
- tUptime /= MIN_S ; /* Convert to minutes. */
- #else
- Microseconds (&uptime) ;
- tUptime = uptime.lo / 60000 ; /* Convert to minutes. */
- #endif /* _AIX */
-
- szpBuffer += strftime (szpBuffer, (lLength - (long) (szpBuffer - szpBuf)),
- "%I:%M%p", tmCurrent) ;
-
- /* Convert uptime to readable format. */
- lDays = tUptime / DAY_M ;
- tUptime %= DAY_M ;
- lHours = tUptime / HOUR_M ;
- tUptime %= HOUR_M ;
- if (lDays > 1)
- szpBuffer += sprintf (szpBuffer, " up %ld days,", lDays) ;
- else if (lDays == 1)
- szpBuffer += sprintf (szpBuffer, " up 1 day,") ;
- szpBuffer += sprintf (szpBuffer, " %02d:%02d,", lHours, (long) tUptime) ;
-
- /* Count the number of users. */
- nUsers = _CountUsers () ;
- if (nUsers == 1)
- szpBuffer += sprintf (szpBuffer, " 1 user") ;
- else
- szpBuffer += sprintf (szpBuffer, " %d users", nUsers) ;
-
- /* Determine the load average. */
- _GetLoads (daLoads) ;
- sprintf (szpBuffer, ", load average: %.2f, %.2f, %.2f\n",
- daLoads[0], daLoads[1], daLoads[2]) ;
-
- return noErr ;
- }
-
- #ifdef _AIX
- void InitApp (void)
- {
- struct utmp sFilter, *spResult ;
- ClientPtr cspInherit ;
-
- /* Get bootime from utmp file. */
- sFilter.ut_type = BOOT_TIME ;
- if (NULL == (spResult = getutid (&sFilter)))
- {
- DBGM ("Couldn't find boot time!\n") ;
- exit (1) ;
- }
-
- _BootTime = spResult->ut_time ;
- DBG ("Boot time was %lu.\n", _BootTime) ;
- endutent () ;
-
- #if SIMPLIFIED
- /* Create the initial, inherited client connection. */
- if (NULL != (cspInherit = NewClient (kUptimeType)))
- ClientSetSession (cspInherit, 0) ;
- #else
- /* Keep track of the utmp file and send updates only when necessary. */
- if (-1 != (_UTmp = open (UTMP_FILE, O_RDONLY)))
- lseek (_UTmp, 0, SEEK_END) ;
- #endif /* !SIMPLIFIED */
- }
-
-
- #if !SIMPLIFIED
- Boolean GetMySelectMask (
- fd_set *fdsMask)
- {
- if (WhoClients == NULL)
- return false ;
- FD_SET (_UTmp, fdsMask) ;
- return true ;
- }
-
- /***
- *** The AIX version of GetWhoString walks the utmp file looking for users.
- *** It stuffs the buffer with the appropriate information.
- ***/
- int GetWhoString (
- char *szpBuf,
- long lLength)
- {
- register char *szpBuffer = szpBuf ;
- register struct utmp *spResult ;
-
- while (NULL != (spResult = getutent ()))
- if ((spResult->ut_type == USER_PROCESS)
- && spResult->ut_user[0])
- {
- struct tm *tmLocal = localtime (&(spResult->ut_time)) ;
- szpBuffer += sprintf (szpBuffer, "%-8.8s %-12.12s",
- spResult->ut_user, spResult->ut_line) ;
- szpBuffer += strftime (szpBuffer,
- (lLength - (long) (szpBuffer - szpBuf)),
- "%b %e %H:%M ", tmLocal) ;
- szpBuffer += sprintf (szpBuffer, "%s \n", spResult->ut_host) ;
- }
- endutent () ;
- }
- #endif /* !SIMPLIFIED */
-
- /***
- *** The Mac version is extremely lazy: It just gets the default user name.
- ***/
- #else /* _AIX */
- int GetWhoString (
- char *szpBuffer,
- long lLength)
- {
- unsigned long ulUser ;
- Str32 sUser ;
-
- if (GetDefaultUser (&ulUser, sUser))
- PStringLen (sUser) = 0 ;
- strncpy (szpBuffer, PStringStr (sUser), PStringLen (sUser)) ;
- return noErr ;
- }
- #endif /* _AIX */
-